import java.util.Vector;

import com.sun.org.apache.xalan.internal.xsltc.compiler.sym;


public class SynchronizedBuffer implements Buffer {
   //private int buffer = -1; // shared by producer and consumer threads
  // private int bufferInUseCount = 0; // count of occupied buffers
   private Vector<KeboardCandidate> buffer=new Vector<KeboardCandidate>();
   private final int size = 20;
   // place value into buffer
   public synchronized void add( KeboardCandidate candidate )
   {
      // for output purposes, get name of thread that called this method
      String name = Thread.currentThread().getName();

      // while there are no empty locations, place thread in waiting state
      while ( size == buffer.size() ) {
         
         // output thread information and buffer information, then wait
         try {
            System.err.println( name + " tries to write." );
            displayState( "Buffer full. " + name + " waits." );
            wait();
         }

         // if waiting thread interrupted, print stack trace
         catch ( InterruptedException exception ) {
            exception.printStackTrace();
         }

      } // end while
        
      buffer.add(candidate); // add to buffer
        
      // indicate producer cannot store another value
      // until consumer retrieves current buffer value
      //++bufferInUseCount;
        
      displayState( name + " writes " );
      
      notifyAll(); // tell waiting thread to enter ready state
        
   } // end method set; releases lock on SynchronizedBuffer 
    
   // return value from buffer
   public synchronized KeboardCandidate remove()
   {
      // for output purposes, get name of thread that called this method
      String name = Thread.currentThread().getName();

      // while no data to read, place thread in waiting state
      while ( buffer.size() == 0 ) {

         // output thread information and buffer information, then wait
         try {
            System.err.println( name + " tries to read." );
            displayState( "Buffer empty. " + name + " waits." );
            wait();
         }

         // if waiting thread interrupted, print stack trace
         catch ( InterruptedException exception ) {
            exception.printStackTrace();
         }

      } // end while

      displayState( name + " reads " );     
      notifyAll(); // tell waiting thread to become ready to execute
      return buffer.remove(0);

   } // end method get; releases lock on SynchronizedBuffer 
    
   // display current operation and buffer state
   public void displayState( String operation )
   {
      StringBuffer outputLine = new StringBuffer( operation );
     // outputLine.setLength( 40 );
      outputLine.append( this.toString() + "\t" + buffer.size() );
      System.err.println( outputLine );
      System.err.println();
   }
   
   public int size(){
	   return buffer.size();
   }
   
   @Override
	public String toString() {
		String ans="";
		boolean first=true;
		for (KeboardCandidate key : buffer) {
			if (first)
				ans=ans+key.getId()+" , ";
			else
				
				ans=ans+" , "+key.getId();
		}
		return "["+ans+"]";
	}
} // end class SynchronizedBuffer

